主页 博客
项目背景
葡萄糖注射液袋装入托盘进行干燥后,会进行翻转放置在生产线上进行传送,但是部分药袋粘在托盘上无法掉落,如果不去掉则会混入下一批次。
下图是一张采用背光的相机采集图片:
难点:
1. 托盘是不锈钢的,无论正面还是侧面都会反光很严重。
2. 现场环境光变化大,会影响相机采集图像的亮度,从而影响边缘。
实验
下面是测试结果:
下面是参考代码:
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
#include <stdio.h> // for use getchar();
#include <stdlib.h> // system("pause");
#include <string>
using namespace cv;
using namespace std;
Mat src, imageSource, threshold_dst, gray_dst, morphology_dst;
int const max_elem = 2;
int const max_kernel_size = 21;
int morph_elem = 0;
int morph_size = 0;
int morph_operator = 0;
int max_operator = 4;
const char* window_name = "Morphology Transformations Demo";
int threshold_elem = 127;
int64 t[30] = { 0 };
double ft[30] = { 0.0 };
double fCPU[30] = { 1000 };
VideoCapture cap;
char filename[80];
int iImage = 629;
int nextImage = 0;
int nextImage1 = 0;
int i;
void findCountour(void)
{
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(threshold_dst, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
Mat imageContours = Mat::zeros(threshold_dst.size(), CV_8UC1);
Mat display;
Mat Contours = Mat::zeros(threshold_dst.size(), CV_8UC1); //绘制
src.copyTo(display);
for (int i = 0; i<contours.size(); i++)
{
/*
//contours[i]代表的是第i个轮廓,contours[i].size()代表的是第i个轮廓上所有的像素点数
for (int j = 0; j<contours[i].size(); j++)
{
//绘制出contours向量内所有的像素点
Point P = Point(contours[i][j].x, contours[i][j].y);
Contours.at<uchar>(P) = 255;
}
*/
drawContours(imageContours, contours, i, Scalar(255), 3, 8, hierarchy);
drawContours(display, contours, i, Scalar(0, 0, 255), 3, 8, hierarchy);
}
imshow("Contours Image", imageContours); //轮廓
//imshow("Point of Contours", Contours); //向量contours内保存的所有轮廓点集
imshow("Source Image", display);
}
void Morphology_Operations(int, void*)
{
// Since MORPH_X : 2,3,4,5 and 6
int operation = morph_operator + 2;
Mat element = getStructuringElement(morph_elem, Size(2 * morph_size + 1, 2 * morph_size + 1), Point(morph_size, morph_size));
//sprintf(filename, "E:/Basler/Cisen203/Basler_acA1300-30gc__21751999__20200520_144409942_%d.tiff", iImage);
//src = imread(filename);
imshow("Source Image", src);
//src.copyTo(imageSource);
morphologyEx(imageSource, morphology_dst, operation, element);
imshow(window_name, morphology_dst);
cvtColor(morphology_dst, gray_dst, COLOR_BGR2GRAY);
threshold(gray_dst, threshold_dst, threshold_elem, 255, 0);
imshow("Threshold", threshold_dst);
findCountour();
}
void Threshold_Operations(int, void*)
{
threshold(gray_dst, threshold_dst, threshold_elem, 255, 0);
imshow("Threshold", threshold_dst);
findCountour();
}
int main(int argc, char *argv[])
{
/*
src = imread("D:/Project/Basler/OpenCV/ConsoleApplication1/cisen1.png");
imshow("Source Image", src);
src.copyTo(imageSource);
*/
cap.open("I:/Basler_acA1300-30gc__21751999__20200520_150933492.avi");
cap >> src;
src.copyTo(imageSource);
int width = cap.get(CV_CAP_PROP_FRAME_WIDTH); //帧宽度
int height = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //帧高度
int frameRate = cap.get(CV_CAP_PROP_FPS); //帧率 x frames/s
int totalFrames = cap.get(CV_CAP_PROP_FRAME_COUNT); //总帧数
cout << "视频宽度=" << width << endl;
cout << "视频高度=" << height << endl;
cout << "视频总帧数=" << totalFrames << endl;
cout << "帧率=" << frameRate << endl;
namedWindow("Source Image", WINDOW_NORMAL); // Create window
resizeWindow("Source Image", 640, 640);
namedWindow("Contours Image", WINDOW_NORMAL); // Create window
resizeWindow("Contours Image", 640, 640);
//namedWindow("Point of Contours", WINDOW_NORMAL); // Create window
//resizeWindow("Point of Contours", 640, 640);
namedWindow(window_name, WINDOW_NORMAL); // Create window
resizeWindow(window_name, 640, 640);
namedWindow("Threshold", WINDOW_NORMAL); // Create window
resizeWindow("Threshold", 640, 640);
createTrackbar("Operator:\n 0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat", window_name, &morph_operator, max_operator, Morphology_Operations);
createTrackbar("Element:\n 0: Rect - 1: Cross - 2: Ellipse", window_name,
&morph_elem, max_elem,
Morphology_Operations);
createTrackbar("Kernel size:\n 2n +1", window_name,
&morph_size, max_kernel_size,
Morphology_Operations);
createTrackbar("Next", window_name,
&nextImage, 1,
Morphology_Operations);
Morphology_Operations(0, 0);
createTrackbar("threshold", "Threshold", &threshold_elem, 255, Threshold_Operations);
Threshold_Operations(0, 0);
waitKey(5000);
while (1)
{
i++;
if (nextImage==1)
{
//iImage++;
if (iImage > 763)iImage = 629;
cap >> src;
src.copyTo(imageSource);
if (src.empty())
{
break;
}
Morphology_Operations(0, 0);
}
if (waitKey(10) >= 0)
break;
}
/* Mat frameFast, frameSlow;
while (1)
{
if (waitKey(0) == 27)
break;
else if (waitKey(0) == 13)
{
cap >> src;
src.copyTo(imageSource);
if (src.empty())
{
//i = 1;
break;
}
Morphology_Operations(0, 0);
}
} */
waitKey(0);
system("Pause");
return 0;
}